import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from sklearn.metrics import roc_curve, auc

sns.set(style="whitegrid")


# 示例数据：不同模型在不同 Top-K 下的表现
def plot_precision_recall_f1(results):
    """
    results = {
        "NCF": {"Precision@5": 0.60, "Recall@5": 0.48, "F1-score@5": 0.53},
        "MF": {"Precision@5": 0.55, "Recall@5": 0.42, "F1-score@5": 0.48},
        ...
    }
    """
    df = pd.DataFrame(results).T

    metrics = ['Precision@5', 'Recall@5', 'F1-score@5']
    for metric in metrics:
        plt.figure(figsize=(8, 5))
        sns.barplot(x=df.index, y=df[metric], palette="viridis")
        plt.title(metric)
        plt.ylabel(metric)
        plt.xlabel("Model")
        plt.tight_layout()
        plt.show()


def plot_rmse_mae(results):
    df = pd.DataFrame(results).T
    df[['RMSE', 'MAE']].plot(kind='bar', figsize=(8, 5), color=['#4e79a7', '#f28e2b'])
    plt.title('RMSE and MAE Comparison')
    plt.ylabel('Error')
    plt.xlabel('Model')
    plt.tight_layout()
    plt.show()


def plot_roc_curves(y_true_dict, y_score_dict):
    """
    y_true_dict = {'NCF': [1, 0, ...], 'MF': [...]}
    y_score_dict = {'NCF': [0.9, 0.1, ...], 'MF': [...]}
    """
    plt.figure(figsize=(8, 6))
    for model in y_true_dict.keys():
        fpr, tpr, _ = roc_curve(y_true_dict[model], y_score_dict[model])
        roc_auc = auc(fpr, tpr)
        plt.plot(fpr, tpr, lw=2, label=f'{model} (AUC = {roc_auc:.2f})')

    plt.plot([0, 1], [0, 1], color='navy', linestyle='--')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('Receiver Operating Characteristic (ROC) Curve')
    plt.legend(loc="lower right")
    plt.show()


def plot_ndcg(results):
    df = pd.DataFrame(results).T
    ndcg_values = [v for k, v in df['NDCG@5'].items()]
    models = df.index.tolist()

    plt.figure(figsize=(8, 5))
    sns.barplot(x=models, y=ndcg_values, palette="magma")
    plt.title('NDCG@5 Comparison')
    plt.ylabel('NDCG@5')
    plt.xlabel('Model')
    plt.tight_layout()
    plt.show()


def plot_coverage(results):
    df = pd.DataFrame(results).T
    coverage_values = [v * 100 for v in df['Coverage'].tolist()]
    models = df.index.tolist()

    plt.figure(figsize=(8, 5))
    sns.barplot(x=models, y=coverage_values, palette="cividis")
    plt.title('Coverage of Recommended Items')
    plt.ylabel('Coverage (%)')
    plt.xlabel('Model')
    plt.tight_layout()
    plt.show()


# 示例调用
if __name__ == "__main__":
    # 示例实验结果（你可以从 evaluate.py 获取）
    results = {
        "NCF": {
            "RMSE": 0.72,
            "MAE": 0.54,
            "Precision@5": 0.60,
            "Recall@5": 0.48,
            "F1-score@5": 0.53,
            "AUC": 0.82,
            "NDCG@5": 0.68,
            "Coverage": 0.75
        },
        "Matrix Factorization": {
            "RMSE": 0.78,
            "MAE": 0.59,
            "Precision@5": 0.55,
            "Recall@5": 0.42,
            "F1-score@5": 0.48,
            "AUC": 0.77,
            "NDCG@5": 0.63,
            "Coverage": 0.68
        },
        "Popularity": {
            "RMSE": 1.10,
            "MAE": 0.85,
            "Precision@5": 0.40,
            "Recall@5": 0.32,
            "F1-score@5": 0.35,
            "AUC": 0.65,
            "NDCG@5": 0.50,
            "Coverage": 0.90
        }
    }

    plot_precision_recall_f1(results)
    plot_rmse_mae(results)
    plot_ndcg(results)
    plot_coverage(results)

    # 示例 AUC 数据（用于演示）
    y_true_dict = {
        "NCF": [1, 0, 1, 1, 0],
        "MF": [1, 0, 1, 0, 0]
    }
    y_score_dict = {
        "NCF": [0.9, 0.1, 0.8, 0.4, 0.2],
        "MF": [0.7, 0.2, 0.6, 0.3, 0.1]
    }
    plot_roc_curves(y_true_dict, y_score_dict)